home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * B G _ U S E R 2 . C
- * BG.EXE user interaction file, the second of two,
- * this version 30th May 1992.
- *
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <conio.h>
- #include <time.h>
- #include "bg.h"
- #include "mousy.h"
-
- /***************************************************************************/
-
- char User_Selects_Move (Dice_t* Dice, /* The dice the user threw */
- Layout_t User_Old, /* Users current situation */
- Layout_t Comp_Old, /* Computers current situation */
- Transit_t* User_Tr, /* How the user moved */
- Transit_t* Comp_Tr, /* Computers new situation */
- Player_t Player) /* The User */
- /*
- PURPOSE: To get the user to move the pieces.
- NOTES: 1) If an error is made or the user hits ESCAPE then we restart
- the whole process, from moving the very first piece.
- 2) We return F10_KEY if the user wants to abandon the game.
- */
- {
- Dice_t Pool ; /* Local copy of input dice */
- short Start,End ; /* Points selected by the user */
- ushort Dice_Used ; /* Index of dice used (0..3) */
-
- short N_Ends ; /* N legal endps poss from start selected */
- short Ends [MAX_MOVES] ; /* List of endps possible */
- short D_I_List [MAX_MOVES] ; /* List of indices into dice pool */
- short End_Index ; /* Index into above two lists */
-
- Transit_t Loc_User ; /* Local copies of input layouts transformed... */
- Transit_t Loc_Comp ; /* ...gradually to output transits */
-
- short Moves_Made ; /* Moves done so far */
- short Moves_To_Make ; /* User MUST make this number of moves */
- boolean Moved ;
- char Key ;
-
- Init_Human_Vars (&Moves_Made,&Pool,Dice, &Loc_User,&Loc_Comp,
- User_Old,Comp_Old) ;
-
- /* Get the computer to tell us how many moves to make */
- Select_Best_Move (Dice,User_Old,Comp_Old,User_Tr,
- Comp_Tr,Player,Legalest) ;
-
- Moves_To_Make = User_Tr->N_Moves ;
- if (Moves_To_Make == 0) {
- /* You are totally blocked */
- Pool.N_Vals = 0 ;
- Show_Dice_List (&Pool) ;
- if (Player == WHITE_PLAYER) {
- Print_Message (W_NOGO_MSG) ;
- } else {
- Print_Message (B_NOGO_MSG) ;
- }
- Seconds_Delay (3) ;
- Clear_Help_Line () ;
- return (NUL) ; /* No keys hit by the user */
- }
-
- while ((Moves_Made < Moves_To_Make) &&
- (Won(Loc_User.Layout,Loc_Comp.Layout)) == NO_WIN) {
- Show_Dice_List (&Pool) ;
- Moved = FALSE ;
- Print_Message (SEL_STA_MSG) ;
- Start = Get_User_Point_Choice (&Key,Player,OUT_ARROW_SHP) ;
- if (Key == F10_KEY) {
- return (F10_KEY) ;
- } else if (Key == F9_KEY) {
- User_Error_Exit () ;
- }
- if (Key != ESC_KEY) {
- N_Ends = Legal_Start (&Loc_User,&Loc_Comp, /* Situation now */
- &Pool, /* Dice to use */
- Start, /* Start point */
- Ends,D_I_List); /* List of possibles */
- if (N_Ends > 0) {
- Print_Message (SEL_END_MSG) ;
- End = Get_User_Point_Choice (&Key,Player,IN_ARROW_SHP) ;
- if (Key == F10_KEY) {
- return (F10_KEY) ;
- }
- if (Key != ESC_KEY) {
- End_Index = Legal_End (End,Ends,N_Ends) ;
- if (End_Index != NOT_VALID_END) {
- Dice_Used = D_I_List [End_Index] ;
- Execute_Move ((char)Start,
- Pool.Values[Dice_Used],
- &Loc_User,&Loc_Comp) ;
- Deplete_Dice_Pool (&Pool,Dice_Used) ;
- Show_Dice_List (&Pool) ;
- Update_User_Move (Loc_User.Layout,
- Loc_Comp.Layout,
- Player) ;
- Moves_Made++ ;
- #if DRODBAR
- Show_Threat (Loc_User.Layout,Loc_Comp.Layout,End) ;
- #endif
- Moved = TRUE ; /* Assume he wants to do it */
- if (Moves_Made == Moves_To_Make) {
- Print_Message (CLK_GO_MSG) ;
- (void)Get_User_Point_Choice (&Key,Player,QUESTION_SHP) ;
- if (Key == F10_KEY) {
- return (Key) ;
- } else if (Key == ESC_KEY) {
- Moved = FALSE ;
- }
- }
- } else {
- Print_Message (CANT_END_MSG) ;
- Seconds_Delay(2) ;
- }
- }
- } else {
- Print_Message (CANT_START_MSG) ;
- Seconds_Delay(1) ;
- }
- }
- if (!Moved) {
- /* The user has to start again, from scratch
- Copy_Dice (&Pool,Dice) ;
- Init_Transit (&Loc_User,User_Old) ;
- Init_Transit (&Loc_Comp,Comp_Old) ;
- Moves_Made = 0 ; */
- Init_Human_Vars (&Moves_Made,&Pool,Dice, &Loc_User,&Loc_Comp,
- User_Old,Comp_Old) ;
- Update_User_Move (Loc_User.Layout,Loc_Comp.Layout,Player) ;
- }
- Clear_Help_Line () ;
- } /* end of while () */
-
- Copy_Transit (User_Tr,&Loc_User) ;
- Copy_Transit (Comp_Tr,&Loc_Comp) ;
-
- /* Show an empty dice list */
- Pool.N_Vals = 0 ;
- Show_Dice_List (&Pool) ;
-
- return (NUL) ; /* No keys hit */
- }
-
- /***************************************************************************/
-
- short Get_User_Point_Choice (char* Key, Player_t Player, short Shape_Code)
- /*
- PURPOSE: To get the user to select a point or to hit the escape key.
- If the user hits a key then we return with Key set, else
- we return the point selected by the user (using mouse or keyboard).
- */
- {
- short User_Input,Mx,My,G_Row,G_Col,Hot_X,Hot_Y ;
-
- if (Shape_Code == NORMAL_SHP) {
- Hot_X = 0 ;
- Hot_Y = 0 ;
- } else {
- Hot_X = 7 ;
- Hot_Y = 7 ;
- }
-
- Show_Mouse_Cursor () ;
- Set_Cursor_Shape (Shape_Code,Hot_X,Hot_Y) ;
-
- (*Key) = NUL ;
- do {
- User_Input = Get_Mouse_Or_Key (&Mx,&My) ;
- if (User_Input & KEY_BIT) {
- if ((User_Input & CHAR_MASK) == ESC_KEY) {
- Hide_Mouse_Cursor () ;
- (*Key) = ESC_KEY ;
- return (0) ;
- }
- } else if (User_Input & FUN_BIT) {
- if ((User_Input & CHAR_MASK) == F10_KEY) {
- Hide_Mouse_Cursor () ;
- (*Key) = F10_KEY ;
- return (0) ;
- }
- if ((User_Input & CHAR_MASK) == F9_KEY) {
- Hide_Mouse_Cursor () ;
- (*Key) = F9_KEY ;
- return (0) ;
- }
- }
- } while (!(User_Input & (LEFT_BIT | RIGHT_BIT))) ;
- Hide_Mouse_Cursor () ;
-
- /* Mx, My now contain the mouse coords */
- if (Pixel_To_Grid (&G_Col,&G_Row,Mx,My)) {
- return (Grid_To_Point (G_Col,G_Row,Player)) ;
- } else {
- return (0) ;
- }
- }
-
- /***************************************************************************/
-
- short Legal_Start (Transit_t* Me, Transit_t* Him, /* These are the... */
- Dice_t* Dice, short Point, /* ...inputs. */
- short End_Points[MAX_MOVES], /* List of end points possible */
- short D_I_List[MAX_MOVES]) /* Dice used for the end point */
- /*
- PURPOSE: Given the inputs we return the number of moves we can make with
- this dice along with with End_Points and D_I_List.
- */
- {
- short epi,d ; /* End Point Index */
-
- epi = 0 ;
-
- for (d = 0 ; d < Dice->N_Vals ; d++) {
- if (Can_Move (Point,Dice->Values[d],Me->Layout,Him->Layout)) {
- End_Points[epi] = Point+Dice->Values[d] ;
- if (End_Points[epi] > HOME_I) {
- End_Points[epi] = HOME_I ;
- }
- D_I_List [epi] = d ;
- epi++ ;
- }
- }
- return (epi) ;
- }
-
- /***************************************************************************/
-
- short Legal_End (short Point, short List[MAX_MOVES], short N_Ends)
- /*
- PURPOSE: The user wants to move to Point, if it's in the list we return
- it's index, else we return NOT_VALID_END
- */
- {
- short p ;
-
- p = 0 ;
- while (p < N_Ends) {
- if (Point == List[p]) {
- return (p) ;
- }
- p++ ;
- }
- return (NOT_VALID_END) ;
- }
-
- /***************************************************************************/
-
- void Update_User_Move (Layout_t User, Layout_t Comp, Player_t Player)
- /*
- PURPOSE: To redraw the board showing the users positions, whether he
- is white or black.
- */
- {
- if (Player == BLACK_PLAYER) {
- Draw_Board_Quick (User,Comp) ;
- } else {
- Draw_Board_Quick (Comp,User) ;
- }
- }
-
- /***************************************************************************/
- #if DRODBAR
- void Show_Threat (Layout_t Me, Layout_t Him, short Point)
- /*
- PURPOSE: To print the threat of him to me at this point.
- */
- {
- short Threat ;
-
- Side_Text (THREAT_ROW,0,"THREAT: ",WHITE) ;
- Threat = Get_Probs (Me,Him,Point,FALSE) ;
- Side_Number (THREAT_ROW,9,Threat,3,WHITE) ;
- }
- #endif
- /***************************************************************************/
-
- void Init_Human_Vars (short* Moves_Made, Dice_t* Pool, Dice_t* Dice,
- Transit_t* Loc_User, Transit_t* Loc_Comp,
- Layout_t User_Old, Layout_t Comp_Old)
- /*
- PURPOSE: To prepare the above vars for a new user move, starting from scratch.
- */
- {
-
- (*Moves_Made) = 0 ; /* He has not yet moved */
- Copy_Dice (Pool,Dice) ; /* So he has all initial dice values */
- Init_Transit (Loc_User,User_Old) ; /* Init the transits from... */
- Init_Transit (Loc_Comp,Comp_Old) ; /* ...what he starts with. */
- }
-
- /***************************************************************************/
-
- void User_Error_Exit (void)
- /*
- PURPOSE: To let the user send a message about something he has noticed
- has gone wrong before abandoning the game. The error message is the
- last thing typed in the file BG??.REC
- */
- {
- extern char Globerr [GERR_LEN] ;
- short i ;
- int ch ;
-
- Clear_Help_Line () ;
- Help_Text (0,"TYPE ERROR DESCRIPTION:",WHITE) ;
- i = 0 ;
- Globerr [i] = NUL ;
- while ((ch = getch ()) != ENTER_KEY) {
- if ((ch == BACK_KEY) && (i > 0)) {
- i-- ;
- Globerr[i] = NUL ;
- } else if (i < (GERR_LEN-1)) {
- Globerr[i] = (char)ch ;
- printf ("%c",ch) ;
- i++ ;
- Globerr[i] = NUL ;
- }
- }
- Error_Exit ("USER HIT F9") ;
- }
-
- /***************************************************************************/
-
- short Key_And_Delay (short Seconds)
- /*
- PURPOSE: To wait Seconds or until a key is hit. We return the key hit
- or zero if we timed out first.
- */
-
- {
- char Key_0 ;
- short Key_Code ;
- time_t Now,Then ;
-
- (void)time (&Then) ;
- do {
- if (kbhit()) {
- Key_0 = (char)getch () ;
- if (Key_0 == FUN_PREFIX) {
- Key_Code = FUN_BIT | getch () ;
- } else {
- Key_Code = KEY_BIT | Key_0 ;
- }
- return (Key_Code) ;
- }
- (void)time(&Now) ;
- } while ((Now - Then) < Seconds) ;
-
- return (0) ;
- }
-
- /***************************************************************************/
-
-